package com.fingard.dsp.bank.directbank.citic04;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.directbank.citic04.util.yldfdemo;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.io.BufferedReader;
import java.io.File;
import java.io.StringReader;
import java.text.MessageFormat;
import java.util.Date;

import static com.fingard.dsp.bank.helpers.YBTHelper.getBatSeqNo;

public class CITIC04BatPayRec extends CITIC04Base implements IBatPayRec {

    @Override
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req1988.reqHeader);
        retAts.reqSeqID = p_req1988.reqBatchNO;
        String ownAct = p_req1988.ownAct;
        try {
            ActSetItem actItem = getBankConfig().getActSetItem(ownAct, "");
            if (actItem == null) {
                retAts.respCode = "0";
                retAts.respInfo = "未找到账号[" + ownAct + "]商户配置信息";
                retAts.reqSeqID = p_req1988.reqBatchNO;
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = FailCode.E9981;
                retAts.writeRetToATS();
                return retAts;
            }

            // 批量代付请求文件内容
            StringBuilder sbFileContent = new StringBuilder();
            // 批次号映射文件内容，以资金批次号命名，文件内容为发送银行的批次号（0001~9999）
            StringBuilder batNoMappingContent = new StringBuilder();

            String tmpLocalMarkPath = getTempFileDirectory() + File.separator + "BatPay";

            String merchantId = actItem.merchantId;
            String tmpBatSeqNo = getBatSeqNo(tmpLocalMarkPath, 4);
            String totalAmt = StringHelper.amountMultiply100(p_req1988.totalAmt);
            String totalNum = p_req1988.totalNum;
            String isPrivate = getBankConfig().getValueAsString("isPrivate");
            if ("1".equals(isPrivate)) {
                isPrivate = "02";
            } else {
                isPrivate = "01";
            }

            String tmpReqHeader = MessageFormat.format("{0}|{1}|{2}|{3}|{4}|{5}||", merchantId, tmpBatSeqNo, Format.Date8Format.format(p_req1988.getPayDateTime()), totalAmt, totalNum, isPrivate);
            sbFileContent.append(tmpReqHeader).append("\r\n");
            batNoMappingContent.append(tmpBatSeqNo);

            while (p_req1988.readRecord()) {
                String orderNumber = p_req1988.readedDetail.askNumber;
                String payAmount = StringHelper.amountMultiply100(p_req1988.readedDetail.payAmount);
                String cardType = "";//收款方账号类型(必填) 01:银行卡，04:单位结算卡
                if ("1".equals(p_req1988.readedDetail.isPrivate)) {
                    cardType = "01";
                } else {
                    cardType = "04";
                }
                String recAct = p_req1988.readedDetail.recAct;
                String recName = p_req1988.readedDetail.recName;
                String province = p_req1988.readedDetail.recAreaName.split("_")[0];
                String city = p_req1988.readedDetail.recAreaName.split("_")[1];
                String recBankName = p_req1988.readedDetail.recBankName;
                String certType = convertCertTypeToBank(p_req1988.readedDetail.certType);
                String certNum = p_req1988.readedDetail.certNum;
                String phone = p_req1988.readedDetail.cellPhone;
                String memo = p_req1988.readedDetail.memo;
                //商户号|商户订单号|金额|收款方账号类型|收款方账号|收款方户名|收款方开户行省|收款方开户行市|收款方开户行名称|收款方证件类型|收款方证件号码|收款方手机号|账单类型|附言|支行|请求方保留域1|请求方保留域2
                String tmpReqBodyDetail = MessageFormat.format("{0}|{1}|{2}|{3}|{4}|{5}|{6}|{7}|{8}|{9}|{10}|{11}||{12}|||", merchantId, orderNumber, payAmount, cardType, recAct, recName, province, city, recBankName, certType, certNum, phone, memo);
                sbFileContent.append(tmpReqBodyDetail).append("\r\n");
            }
            String tmpFileContent = sbFileContent.toString();
            WriteBankLogLn2("批次请求文件内容:\r\n" + tmpFileContent);

            //批次号映射文件处理
            String tmpUploadFileName = p_req1988.reqBatchNO + ".txt";
            String tmpUploadFilePath = tmpLocalMarkPath + File.separator + tmpUploadFileName;
            String tmpBatNoMappingContent = batNoMappingContent.toString();
            WriteBankLogLn2("批次号映射文件保存本地路径: " + tmpUploadFilePath);
            WriteBankLogLn2("批次号映射文件内容: " + tmpBatNoMappingContent);
            FileHelper.writeFile(tmpUploadFilePath, tmpBatNoMappingContent, getCharset());

            //批量代付请求文件名
            String tmpFileName = merchantId + Format.DateTime14Format.format(new Date()) + tmpBatSeqNo + ".txt";

            //批量代付文件内容压缩流(zip 压缩字节流)
            String fileContent = yldfdemo.zip(tmpFileContent);

            CITIC04Header header = new CITIC04Header();
            header.tranCode = CITIC04TransCode.deal_198801_B0001;
            header.msgno = p_req1988.reqBatchNO;
            header.receiveNode = getBankConfig().getMapValueByKey("bankBranch", ownAct);

            XmlTextWriter xmlWriter = new XmlTextWriter();
            xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"" + getCharset() + "\"?>");
            xmlWriter.writeStartElement("request");
            xmlWriter.writeElementString("tranCode", "B0001"); // 交易代码
            xmlWriter.writeStartElement("body");
            xmlWriter.writeElementString("merchantId", actItem.merchantId);
            xmlWriter.writeElementString("orderDate", Format.Date8Format.format(new Date()));
            xmlWriter.writeElementString("orderTime", Format.Time6Format.format(new Date()));
            xmlWriter.writeElementString("fileName", tmpFileName);
            xmlWriter.writeElementString("fileContent", fileContent);
            xmlWriter.writeElementString("batchNo", tmpBatSeqNo);//0000~9999
            xmlWriter.writeElementString("sumAmount", StringHelper.amountMultiply100(p_req1988.totalAmt));
            xmlWriter.writeElementString("countItems", p_req1988.totalNum);
            xmlWriter.writeEndDocument();
            String tmpStrPlain = xmlWriter.toXmlString();
            WriteBankLogLn2("发送银行请求数据明文:\r\n" + tmpStrPlain);

            String[] tmpRetStr = sendToBank(tmpStrPlain, header, actItem);

            if (tmpRetStr[0].length() == 0) {
                WriteBankLogStep3(tmpRetStr[1]);
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetStr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpErrCode = tmpBkReader.getFirstText("/ROOT/errCode");
                    String tmpErrMsg = tmpBkReader.getFirstText("/ROOT/errMsg");
                    if (StringHelper.isNullOrEmpty(tmpErrCode)) {
                        String encrypt = tmpBkReader.getFirstText("/ROOT/encrypt");
                        String signature = tmpBkReader.getFirstText("/ROOT/signature");
                        String[] respData = decryptMessage(encrypt, signature, actItem);
                        if ("fail".equals(respData[0])) {
                            retAts.respCode = "-1";
                            retAts.respInfo = "验签失败！";
                            retAts.writeRetToATS();
                            return retAts;
                        }
                        WriteBankLogLn2("解密银行返回报文: " + respData[1]);
                        XmlTextReader tmpBkReaders = loadBankRespXmlReader(respData[1], tmpSbMsg);
                        if (tmpBkReaders != null) {
                            String tmpRespCode = tmpBkReaders.getFirstText("/response/body/errCode");
                            String tmpRespInfo = tmpBkReaders.getFirstText("/response/body/errMsg");
                            if (tmpRespCode != null) {
                                retAts.respCode = "0";
                                retAts.respInfo = tmpRespInfo;
                                retAts.transState = tmpRespCode;
                                retAts.payInfoCode = tmpRespCode;
                            } else {
                                retAts.respCode = "-1";
                                retAts.respInfo = tmpRespInfo;
                            }
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = tmpSbMsg.toString();
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpErrMsg;
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpRetStr[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeRetToATS();
        return retAts;
    }


    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req1998.reqHeader);
        retAts.reqSeqID = p_req1998.reqBatchNO;
        String ownAct = p_req1998.ownAct;
        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_req1998.ownAct, "");
            if (actItem == null) {
                retAts.respCode = "-1";
                retAts.respInfo = "未找到账号[" + ownAct + "]商户配置信息";
                retAts.writeAfterDetail();
                return retAts;
            }

            String merchantId = actItem.merchantId;

            // 读取接收资金报文中的批次号对应的发送银行的批次号
            String tmpBatNoMappingPath = getTempFileDirectory(p_req1998.getBgnDateTime()) + File.separator + "BatPay" + File.separator + p_req1998.reqBatchNO + ".txt";
            WriteBankLogLn2("批次号映射文件保存本地路径:" + tmpBatNoMappingPath);
            if (!new File(tmpBatNoMappingPath).exists()) {
                retAts.respCode = "-1";
                retAts.respInfo = "本地批次号映射文件不存在!";
                return retAts;
            }
            String batchNo = FileHelper.readFileText(tmpBatNoMappingPath, getCharset());
            WriteBankLogLn2("本地批量代付批次号映射文件内容:\r\n" + batchNo);

            String fileName = merchantId + Format.DateTime14Format.format(p_req1998.getBgnDateTime()) + batchNo + ".txt";

            CITIC04Header header = new CITIC04Header();
            header.tranCode = CITIC04TransCode.deal_1998_B0002;
            header.msgno = p_req1998.reqBatchNO;
            header.receiveNode = getBankConfig().getMapValueByKey("bankBranch", ownAct);

            XmlTextWriter xmlWriter = new XmlTextWriter();
            xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"" + getCharset() + "\"?>");
            xmlWriter.writeStartElement("request");
            xmlWriter.writeElementString("tranCode", "B0002"); // 交易代码
            xmlWriter.writeStartElement("body");
            xmlWriter.writeElementString("merchantId", merchantId);
            xmlWriter.writeElementString("orderDate", Format.Date8Format.format(new Date()));
            xmlWriter.writeElementString("orderTime", Format.Time6Format.format(new Date()));
            xmlWriter.writeElementString("fileName", fileName);
            xmlWriter.writeElementString("batchNo", batchNo);
            xmlWriter.writeElementString("orgTradeDate", Format.Date8Format.format(p_req1998.getBgnDateTime()));
            xmlWriter.writeEndDocument();

            String tmpStrPlain = xmlWriter.toXmlString();
            WriteBankLogLn2("发送银行请求数据明文:\r\n" + tmpStrPlain);

            String[] tmpRetStr = sendToBank(tmpStrPlain, header, actItem);
            if (tmpRetStr[0].length() == 0) {
                WriteBankLogStep3(tmpRetStr[1]);
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetStr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpErrCode = tmpBkReader.getFirstText("/ROOT/errCode");
                    String tmpErrMsg = tmpBkReader.getFirstText("/ROOT/errMsg");
                    if (StringHelper.isNullOrEmpty(tmpErrCode)) {
                        String encrypt = tmpBkReader.getFirstText("/ROOT/encrypt");
                        String signature = tmpBkReader.getFirstText("/ROOT/signature");
                        String[] respData = decryptMessage(encrypt, signature, actItem);
                        if ("fail".equals(respData[0])) {
                            retAts.respCode = "-1";
                            retAts.respInfo = "验签失败！";
                            retAts.writeAfterDetail();
                            return retAts;
                        }
                        WriteBankLogLn2("解密银行返回报文: " + respData[1]);
                        XmlTextReader tmpBkReaders = loadBankRespXmlReader(respData[1], tmpSbMsg);
                        if (tmpBkReaders != null) {
                            retAts.respCode = "0";
                            String resultFileName = tmpBkReaders.getFirstText("/response/body/resultFileName");
                            if (StringHelper.hasAnyChar(resultFileName)) {
                                String tmpResultFileContent = tmpBkReaders.getFirstText("/response/body/resultFileContent");
                                //批量代付结果文件内容压缩流(zip 压缩字节流)解压缩
                                String resultFileContent = yldfdemo.unzip(tmpResultFileContent);

                                WriteBankLogLn2("银行返回文件内容:\r\n" + resultFileContent);
                                if (StringHelper.hasAnyChar(resultFileContent)) {
                                    StringReader strReader = new StringReader(resultFileContent);
                                    BufferedReader tmpReader = new BufferedReader(strReader);
                                    tmpReader.readLine();
                                    while (true) {
                                        String eachline = tmpReader.readLine();
                                        if (eachline == null) {
                                            break;
                                        }
                                        if (eachline.indexOf('|') > 0) {
                                            RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();
                                            String[] detailNodes = eachline.split("\\|");
                                            tmpRetDetail.payAmount = StringHelper.amountDivide100(detailNodes[2]);
                                            tmpRetDetail.recName = detailNodes[5];
                                            tmpRetDetail.recAct = detailNodes[4];
                                            tmpRetDetail.postScript = detailNodes[1];
                                            tmpRetDetail.result = detailNodes[17];
                                            tmpRetDetail.payInfoCode = detailNodes[17];
                                            tmpRetDetail.memo = detailNodes[18];
                                            retAts.writeRetDetail(tmpRetDetail);
                                        } else {
                                            retAts.respCode = "-1";
                                            retAts.respInfo = "银行返回明细数据格式非法!";
                                        }
                                    }
                                } else {
                                    retAts.respCode = "-1";
                                    retAts.respInfo = "批量代付结果文件内容为空!";
                                }
                            } else {
                                retAts.respCode = "-1";
                                retAts.respInfo = "批量文件银行尚未处理完成，请稍后查询!";
                            }

                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = tmpSbMsg.toString();
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpErrMsg;
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpRetStr[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }
        retAts.writeAfterDetail();
        return retAts;
    }

    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        return null;
    }

    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        return null;
    }
}
